package com.sgzn.sgpay.service.impl;

import com.sgzn.sgpay.enums.DeviceType;
import com.sgzn.sgpay.enums.SgsResponseCode;
import com.sgzn.sgpay.model.request.SgsDeviceIncomeRequest;
import com.sgzn.sgpay.model.response.CurrentPageInfo;
import com.sgzn.sgpay.model.response.SgsResultResponse;
import com.sgzn.sgpay.model.response.result.SgsDeviceIncomeResult;
import com.sgzn.sgpay.model.response.vo.DeviceIncomeVo;
import com.sgzn.sgpay.persistence.dao.TBizOrderReadMapper;
import com.sgzn.sgpay.persistence.dao.TDeviceMapper;
import com.sgzn.sgpay.persistence.domain.TDevice;
import com.sgzn.sgpay.persistence.domain.TDeviceExample;
import com.sgzn.sgpay.persistence.domain.TShop;
import com.sgzn.sgpay.persistence.manager.PresentReadManager;
import com.sgzn.sgpay.persistence.manager.ShopDaoManager;
import com.sgzn.sgpay.persistence.request.TBizOrderReadDeviceRequest;
import com.sgzn.sgpay.persistence.response.TBizOrderRead;
import com.sgzn.sgpay.persistence.response.TPresentRead;
import com.sgzn.sgpay.service.SgsDeviceIncomeService;
import com.sgzn.sgpay.service.support.SgsResponseUtil;
import com.sgzn.sgpay.util.PageCalculator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 设备经营分析服务实现类
 * @author huangsenguang
 * @version Id: SgsDeviceIncomeServiceImpl.java, v 0.1 2018/5/30 20:08 huangsenguang Exp $$
 */
@Slf4j
@Service
public class SgsDeviceIncomeServiceImpl implements SgsDeviceIncomeService {
    @Autowired
    private TDeviceMapper tDeviceMapper;

    @Resource
    private ShopDaoManager shopDaoManager;

    @Resource
    private TBizOrderReadMapper tBizOrderReadMapper;


    @Autowired
    private PresentReadManager presentReadManager;

    @Override
    public SgsResultResponse<SgsDeviceIncomeResult> queryInfo(SgsDeviceIncomeRequest request) {

        try {
            TDeviceExample example = this.getTDeviceExampleByPage(request);
            int totalCount = this.tDeviceMapper.countByExample(example);//获取总数
            CurrentPageInfo pageInfo = PageCalculator.getPageInfo(totalCount, request.getPageQueryParam().getPageSize(),
                    request.getPageQueryParam().getCurrentPage());

            StringBuffer clause = new StringBuffer();
            //加上起始和结束行号进行列表查询
            clause.append("shop_id, updated_at desc ");
            clause.append("limit ").append(pageInfo.getStartIndex()).
                    append(",").append(pageInfo.getPageSize());
            example.setOrderByClause(clause.toString());
            List<TDevice> tDeviceList = tDeviceMapper.selectByExample(example);
            log.info("tDeviceList:{}", tDeviceList);
            if (CollectionUtils.isEmpty(tDeviceList)) {
                return getEmptyResponse(totalCount, pageInfo);
            }
            final int SIZE = tDeviceList.size();
            HashMap<String, TDevice> deviceMap = new HashMap<>(SIZE);//获取设备map
            Set<String> shopIdSet = new HashSet<>(SIZE);
            for (TDevice tDevice : tDeviceList) {
                deviceMap.put(tDevice.getDeviceId(), tDevice);
                shopIdSet.add(tDevice.getShopId());
            }
            List<String> deviceIdList = new ArrayList<>(SIZE);//获得deviceId 集合
            deviceIdList.addAll(deviceMap.keySet());
            List<String> shopIdList = new ArrayList<>(SIZE);//获得shopId 集合
            shopIdList.addAll(shopIdSet);
            log.info("shopIdList:{}", shopIdList);
            Map<String, String> shopMap = getShopMap(shopIdList); //获取shopName Map

            //在线支付map
            Map<String, BigDecimal> bizOrderMap = getOnlineAmountMap(deviceIdList);

            List<TPresentRead> records = presentReadManager.gettPresentReads(request.getBeginTime(), request.getEndTime(), deviceIdList);
            Map<String, TPresentRead> presentRecordMap = new HashMap<>(tDeviceList.size());//礼品集合map
            for (TPresentRead record : records) {
                presentRecordMap.put(record.getDeviceId(), record);
            }

            SgsDeviceIncomeResult result = getSgsDeviceIncomeResult(totalCount, pageInfo, tDeviceList, SIZE, shopMap, bizOrderMap, presentRecordMap);
            return SgsResponseUtil.INSTANCE.success(result);
        } catch (Exception e) {
            log.error("设备经营分析服务异常：",e);
            return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C503.getResponseCode(),SgsResponseCode.C503.getResponseDesc());
        }
    }

    private SgsResultResponse<SgsDeviceIncomeResult> getEmptyResponse(int totalCount, CurrentPageInfo pageInfo) {
        SgsDeviceIncomeResult result = new SgsDeviceIncomeResult();
        result.setCurrentPage(pageInfo.getCurrentPage());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotalCount(totalCount);
        result.setTotalPage(pageInfo.getTotalPage());
        List<DeviceIncomeVo> shopIncomeVoList = new ArrayList<>(0);
        result.setDeviceIncomeVoList(shopIncomeVoList);
        return SgsResponseUtil.INSTANCE.success(result);
    }

    /**
     * 组装响应结果
     * @param totalCount
     * @param pageInfo
     * @param tDeviceList
     * @param SIZE
     * @param shopMap
     * @param bizOrderMap
     * @param presentRecordMap
     * @return
     */
    private SgsDeviceIncomeResult getSgsDeviceIncomeResult(int totalCount, CurrentPageInfo pageInfo, List<TDevice> tDeviceList, int SIZE, Map<String, String> shopMap, Map<String, BigDecimal> bizOrderMap, Map<String, TPresentRead> presentRecordMap) {
        SgsDeviceIncomeResult result = new SgsDeviceIncomeResult();
        result.setCurrentPage(pageInfo.getCurrentPage());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotalCount(totalCount);
        result.setTotalPage(pageInfo.getTotalPage());
        List<DeviceIncomeVo> shopIncomeVoList = new ArrayList<>(SIZE);
        for (TDevice tDevice : tDeviceList) {
            String deviceId = tDevice.getDeviceId();
            DeviceIncomeVo deviceIncomeVo = new DeviceIncomeVo();
            TPresentRead tPresentRead = presentRecordMap.get(deviceId);
            int totalPresentBalance = 0;
            if (tPresentRead != null) {
                totalPresentBalance = tPresentRead.getPresentPrice() * tPresentRead.getPresentAmount();
                deviceIncomeVo.setConsumePresentAmount(tPresentRead.getPresentAmount());
            }
            deviceIncomeVo.setDeviceId(deviceId);
            deviceIncomeVo.setShopId(tDevice.getShopId());
            deviceIncomeVo.setDeviceName(tDevice.getDeviceName());
            deviceIncomeVo.setShopName(shopMap.get(tDevice.getShopId()));
            deviceIncomeVo.setDeviceType(DeviceType.getDescByCode(tDevice.getDeviceType()));
            deviceIncomeVo.setOnlineAmount(bizOrderMap.get(deviceId));
            deviceIncomeVo.setConsumePresentBalance(totalPresentBalance);
            if (bizOrderMap.get(deviceId) != null) {
                deviceIncomeVo.setTotalIncome(bizOrderMap.get(deviceId).add(new BigDecimal(totalPresentBalance)));//设备收益总计
            } else {
                deviceIncomeVo.setTotalIncome(new BigDecimal(totalPresentBalance));//设备收益总计
            }
            shopIncomeVoList.add(deviceIncomeVo);
        }
        result.setDeviceIncomeVoList(shopIncomeVoList);
        return result;
    }

    private Map<String, String> getShopMap(List<String> shopIdList) {
        List<TShop> tShopList = this.shopDaoManager.getTShopList(shopIdList);
        HashMap<String, String> shopMap = new HashMap<>();
        for (TShop tShop : tShopList) {
            shopMap.put(tShop.getShopId(), tShop.getShopName());
        }
        return shopMap;
    }

    /**
     * 获取查询对象
     *
     * @param request
     * @return
     */
    private TDeviceExample getTDeviceExampleByPage(SgsDeviceIncomeRequest request) {
        TDeviceExample countExample = new TDeviceExample();
        TDeviceExample.Criteria cra = countExample.createCriteria();
        cra.andMerchantIdEqualTo(request.getMchId());
        cra.andUpdatedAtBetween(request.getBeginTime(), request.getEndTime());
        if (CollectionUtils.isEmpty(request.getDeviceTypeList())) {
            cra.andDeviceTypeIn(getDeviceTypeList());
        } else {
            cra.andDeviceTypeIn(request.getDeviceTypeList());//页面传过来有值
        }
        return countExample;
    }

    /**
     * 在线支付
     * @param deviceIdList
     * @return
     */
    private Map<String,BigDecimal> getOnlineAmountMap(List<String> deviceIdList) {
        TBizOrderReadDeviceRequest tBizOrderReadDeviceRequest = new TBizOrderReadDeviceRequest();
        tBizOrderReadDeviceRequest.setDeviceIdList(deviceIdList);
        List<TBizOrderRead> respList = tBizOrderReadMapper.queryByDeviceIds(tBizOrderReadDeviceRequest);
        Map<String, BigDecimal> bizOrderMap = new HashMap<>(respList.size());
        for (TBizOrderRead tBizOrderRead : respList) {
            bizOrderMap.put(tBizOrderRead.getDeviceId(), tBizOrderRead.getSumAmount());
        }
        return bizOrderMap;
    }

    /**
     * 获取设备类型列表
     * @return
     */
    public List<String> getDeviceTypeList() {
        List<String> deviceTypeList = new ArrayList<>(2);
        for(DeviceType single : DeviceType.values()){
            deviceTypeList.add(single.getCode());
        }
        return deviceTypeList;
    }
}

